﻿using com.nm.Helper;
using com.nm.interfaces;
using System;
using System.Collections.Generic;
using System.Linq;

namespace com.nm.library.Factorys
{
    /// <summary>
    /// 工厂模式
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="TF"></typeparam>
    public class BaseFactory<T, TF> where TF : T
    {
        private static T _cache;

        /// <summary>
        /// 获取服务
        /// </summary>
        /// <param name="FactoryType"></param>
        /// <returns></returns>
        public static T GetService(Type FactoryType)
        {
            if (FactoryType == null || FactoryType.GetInterfaces().Any(t => t == typeof(T)) == false)
                _cache = (T)Activator.CreateInstance<TF>();
            else
                _cache = (T)Activator.CreateInstance(FactoryType);
            //_cache = (ICache)Activator.CreateInstance(FactoryType);
            return _cache;
        }
    }

    /// <summary>
    /// 生成工厂
    /// </summary>
    public static class FactoryMaker
    {
        private static readonly Dictionary<string, object> Dictionary = new Dictionary<string, object>();

        /// <summary>
        /// 获取工厂
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="typeName"></param>
        /// <returns></returns>
        public static T Get<T>(string typeName) where T : IFactory
        {
            typeName = typeName.Trim().Replace(" ", "");
            if (Dictionary.Any(i => i.Key == typeName))
            {
                return (T)Dictionary[typeName];
            }
            var type = Type.GetType(typeName);
            if (type == null) throw new NullReferenceException(typeName);
            var o = (T)Activator.CreateInstance(type);
            if (o == null) throw new NullReferenceException(typeName);
            Dictionary.Add(typeName, o);
            return o;
        }

        /// <summary>
        /// 从web.config中读取配置信息
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="configKey"></param>
        /// <param name="typeName">备用</param>
        /// <returns></returns>
        public static T Get<T>(string configKey, string typeName) where T : IFactory
        {
            return Get<T>(ConfigurationHelper.Get(configKey, typeName));
        }
    }
}